#include "git-fetch-context.h"

#include "git-cert-request.h"

namespace git
{

FetchContext::FetchContext(const Cert &cert, git_fetch_options &opt)
    : certProvider_(cert) {

    bind(opt);
}

void FetchContext::bind(git_fetch_options &opt) const {
    opt.callbacks.sideband_progress = onFetchSidebandProgress;
    opt.callbacks.transfer_progress = onFetchTransferProgress;
    opt.callbacks.credentials = onFetchCredential;
    opt.callbacks.payload = const_cast<FetchContext *>(this);
}

void FetchContext::setProgressCallback(ProgressCallback &&callback) {
    progressCallback_ = std::move(callback);
}

int FetchContext::onFetchSidebandProgress(const char *str, int len, void *payload) {
    FetchContext *p = reinterpret_cast<FetchContext *>(payload);
    if (p && str && p->progressCallback_) {
        p->progressCallback_(str);
    }
    return 0;
}

int FetchContext::onFetchTransferProgress(const git_indexer_progress *stats, void *payload) {
    FetchContext *p = reinterpret_cast<FetchContext *>(payload);
    if (p && stats) {
        // TODO
    }
    return 0;
}

int FetchContext::onFetchCredential(
    git_credential **out,
    const char *url,
    const char *usernameFromUrl,
    unsigned int allowedTypes,
    void *payload) {

    FetchContext *p = reinterpret_cast<FetchContext *>(payload);
    if (!p) {
        return -1;
    }

    if (!out) {
        return -1;
    }

    const CertRequest req(url, usernameFromUrl, allowedTypes);
    git_credential *cred = p->certProvider_.provide(req);
    if (!cred) {
        return -1;
    }

    *out = cred;
    return 0;
}

} // namespace git
